<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="RTOS TencentOS-tiny">
    <meta name="description" content="嵌入式 STM32 物联网领域的教程及精彩内容分享">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>08-CMSIS RTOS API用法详解及示例 | Mculover666</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 5.4.0"></head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">Mculover666</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="" class="waves-effect waves-light">

      
      <i class="fas fa-list" style="zoom: 0.6;"></i>
      
      <span>系列教程</span>
      <i class="fas fa-chevron-down" aria-hidden="true" style="zoom: 0.6;"></i>
    </a>
    <ul class="sub-nav menus_item_child ">
      
      <li>
        <a href="/posts/578764034/">
          
          <span>STM32CubeMX</span>
        </a>
      </li>
      
    </ul>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a target="_blank" rel="noopener" href="https://blog.csdn.net/Mculover666" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>CSDN</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/download" class="waves-effect waves-light">
      
      <i class="fas fa-download" style="zoom: 0.6;"></i>
      
      <span>资源下载</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">Mculover666</div>
        <div class="logo-desc">
            
            嵌入式 STM32 物联网领域的教程及精彩内容分享
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="javascript:;">
			
				<i class="fa-fw fas fa-list"></i>
			
			系列教程
			<span class="m-icon"><i class="fas fa-chevron-right"></i></span>
		</a>
            <ul  style="background:  ;" >
              
                <li>

                  <a href="/posts/578764034/ " style="margin-left:75px">
				  
		          <span>STM32CubeMX</span>
                  </a>
                </li>
              
            </ul>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a target="_blank" rel="noopener" href="https://blog.csdn.net/Mculover666" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			CSDN
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/download" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-download"></i>
			
			资源下载
		</a>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://github.com/blinkfox/hexo-theme-matery" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://github.com/blinkfox/hexo-theme-matery" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/17.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">08-CMSIS RTOS API用法详解及示例</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/RTOS%E5%86%85%E5%8A%9F%E4%BF%AE%E7%82%BC%E8%AE%B0/">
                                <span class="chip bg-color">RTOS内功修炼记</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/RTOS/" class="post-category">
                                RTOS
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2020-08-01
                </div>
                

                

                

                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>
        </div>
        <hr class="clearfix">

        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <h1 id="1-CMSIS-RTOS-API"><a href="#1-CMSIS-RTOS-API" class="headerlink" title="1. CMSIS-RTOS API"></a>1. CMSIS-RTOS API</h1><p>CMSIS-RTOS API是ARM公司为RTOS内核制定的一套通用接口协议，它提供了一套<strong>标准的API接口</strong>，可以移植到各种各样的RTOS上，使得上层的软件、中间件、库以及其他组件在不同的RTOS之上都可以正常工作。</p>
<p>这套API表现为两个文件：cmsis-os.h和cmsis-os.c，也就是说，不同的RTOS内核分别用自己的一套东西去适配.c文件中的接口，而用户只需要调用.h文件中给出的API编写应用。</p>
<p>本文会列举性的给出CMSIS-RTOS有哪些API和宏定义，并给出每类API的使用demo，学习者只需要了解这些东西，能看懂用CMSIS-RTOS API编写的应用程序即可~</p>
<p>在TencentOS-tiny中如下。</p>
<ul>
<li>基于TencentOS-tiny的CMSIS-RTOS API v1.02版本实现：<ul>
<li><code>cmsis_os.h</code></li>
<li><code>cmsis_os.c</code></li>
</ul>
</li>
<li>基于TencentOS-tiny的CMSIS-RTOS API v2.1.3版本实现：<ul>
<li><code>cmsis_os2.h</code></li>
<li><code>cmsis_os2.c</code></li>
</ul>
</li>
</ul>
<p>CMSIS-RTOS API的整体架构如下图：<br><img src="https://img-blog.csdnimg.cn/20200801081849297.png#pic_center"></p>
<h1 id="2-CMSIS-RTOS-API列表"><a href="#2-CMSIS-RTOS-API列表" class="headerlink" title="2. CMSIS-RTOS API列表"></a>2. CMSIS-RTOS API列表</h1><p>下面列出了 CMSIS-RTOS API <font color="red">v1.02</font> 版本提供的所有API。</p>
<p>CMSIS-RTOS 所有API使用的错误码（cmsis-os.h）：</p>
<pre><code class="c">typedef enum &#123;
    osOK                    =     0,       ///&lt; function completed; no error or event occurred.
    osEventSignal           =  0x08,       ///&lt; function completed; signal event occurred.
    osEventMessage          =  0x10,       ///&lt; function completed; message event occurred.
    osEventMail             =  0x20,       ///&lt; function completed; mail event occurred.
    osEventTimeout          =  0x40,       ///&lt; function completed; timeout occurred.
    osErrorParameter        =  0x80,       ///&lt; parameter error: a mandatory parameter was missing or specified an incorrect object.
    osErrorResource         =  0x81,       ///&lt; resource not available: a specified resource was not available.
    osErrorTimeoutResource  =  0xC1,       ///&lt; resource not available within given time: a specified resource was not available within the timeout period.
    osErrorISR              =  0x82,       ///&lt; not allowed in ISR context: the function cannot be called from interrupt service routines.
    osErrorISRRecursive     =  0x83,       ///&lt; function called multiple times from ISR with same object.
    osErrorPriority         =  0x84,       ///&lt; system cannot determine priority or thread has illegal priority.
    osErrorNoMemory         =  0x85,       ///&lt; system is out of memory: it was impossible to allocate or reserve memory for the operation.
    osErrorValue            =  0x86,       ///&lt; value of a parameter is out of range.
    osErrorOS               =  0xFF,       ///&lt; unspecified RTOS error: run-time error but no other error message fits.
    os_status_reserved      =  0x7FFFFFFF  ///&lt; prevent from enum down-size compiler optimization.
&#125; osStatus;
</code></pre>
<p>CMSIS-RTOS API一些可选项控制是否开启（cmsis-os.h）：</p>
<pre><code class="c">#define osFeature_MainThread   1       ///&lt; main thread      1=main can be thread, 0=not available
#define osFeature_Pool         1       ///&lt; Memory Pools:    1=available, 0=not available
#define osFeature_MailQ        1       ///&lt; Mail Queues:     1=available, 0=not available
#define osFeature_MessageQ     1       ///&lt; Message Queues:  1=available, 0=not available
#define osFeature_Signals      0       ///&lt; maximum number of Signal Flags available per thread
#define osFeature_Semaphore    30       ///&lt; maximum count for \ref osSemaphoreCreate function
#define osFeature_Wait         0       ///&lt; osWait function: 1=available, 0=not available
#define osFeature_SysTick      1       ///&lt; osKernelSysTick functions: 1=available, 0=not available
</code></pre>
<h2 id="2-1-内核信息和控制（Kernel-information-and-control）"><a href="#2-1-内核信息和控制（Kernel-information-and-control）" class="headerlink" title="2.1. 内核信息和控制（Kernel information and control）"></a>2.1. 内核信息和控制（Kernel information and control）</h2><table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osKernelInitialize</td>
<td align="center">初始化RTOS内核</td>
</tr>
<tr>
<td align="center">osKernelStart</td>
<td align="center">启动RTOS内核</td>
</tr>
<tr>
<td align="center">osKernelRunning</td>
<td align="center">Query if the RTOS kernel is running</td>
</tr>
<tr>
<td align="center">osKernelSysTick (可选)</td>
<td align="center">Get RTOS kernel system timer counter</td>
</tr>
<tr>
<td align="center">osKernelSysTickFrequency (可选)</td>
<td align="center">RTOS kernel system timer frequency in Hz</td>
</tr>
<tr>
<td align="center">osKernelSysTickMicroSec (可选)</td>
<td align="center">Convert microseconds value to RTOS kernel system timer value</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osKernelInitialize</code></p>
<pre><code class="c">osStatus osKernelInitialize(void);
</code></pre>
<p>返回值：status code</p>
</li>
<li><p><code>osKernelStart</code></p>
<pre><code class="c">osStatus osKernelStart(void);
</code></pre>
<p>返回值：status code</p>
</li>
<li><p><code>osKernelRunning</code></p>
<pre><code class="c">int32_t osKernelRunning(void);
</code></pre>
<p>返回值：0表示RTOS未启动，1表示RTOS已经启动</p>
</li>
<li><p><code>osKernelSysTick</code></p>
<pre><code class="c">uint32_t osKernelSysTick(void);
</code></pre>
<p>返回值：RTOS内核系统当前的时间</p>
</li>
</ul>
<h2 id="2-2-线程管理（Thread-management）"><a href="#2-2-线程管理（Thread-management）" class="headerlink" title="2.2. 线程管理（Thread management）"></a>2.2. 线程管理（Thread management）</h2><blockquote>
<p><code>##</code>连接符的作用是连接两个字符串，合为一个字符串。</p>
</blockquote>
<p>CMSIS-RTOS API 存放线程参数管理的结构体如下：</p>
<pre><code class="c">typedef struct os_thread_def &#123;
    char           *name;       ///&lt; Thread name
    os_pthread      pthread;    ///&lt; start address of thread function
    osPriority      tpriority;  ///&lt; initial thread priority
    uint32_t        instances;  ///&lt; maximum number of instances of that thread function
    k_stack_t      *stackbase;  ///&lt; base address of task
    uint32_t        stacksize;  ///&lt; stack size requirements in bytes; 0 is default stack size
    k_timeslice_t   timeslice;  ///&lt; timeslice
    k_task_t       *task;
&#125; osThreadDef_t;
</code></pre>
<p>CMSIS-RTOS API 定义线程的宏如下：</p>
<pre><code class="c">#define osThreadDef(name, priority, instances, stacksz)  \
    k_task_t task_handler_##name; \
    k_stack_t task_stack_##name[(stacksz)]; \
    const osThreadDef_t os_thread_def_##name = \
        &#123; #name, (os_pthread)(name), (osPriority)(priority), (instances), \
        (&amp;((task_stack_##name)[0])), (stacksz), ((k_timeslice_t)0u), (&amp;(task_handler_##name)) &#125;
</code></pre>
<blockquote>
<p>宏定义中的 instances 表示基于此任务参数，创建出几个任务实例，比如instances为2，则会创建出两个任务。</p>
</blockquote>
<p>CMSIS-RTOS API定义的获取线程参数结构体的宏如下：</p>
<pre><code class="c">#define osThread(name)  \
    &amp;os_thread_def_##name
</code></pre>
<p>管理线程参数的API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osThreadCreate</td>
<td align="center">创建线程并开始执行</td>
</tr>
<tr>
<td align="center">osThreadTerminate</td>
<td align="center">停止线程执行</td>
</tr>
<tr>
<td align="center">osThreadYield</td>
<td align="center">线程主动让出</td>
</tr>
<tr>
<td align="center">osThreadGetID</td>
<td align="center">获取当前正在运行线程的ID</td>
</tr>
<tr>
<td align="center">osThreadSetPriority</td>
<td align="center">改变线程优先级</td>
</tr>
<tr>
<td align="center">osThreadGetPriority</td>
<td align="center">获取线程优先级</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osThreadCreate</code></p>
<pre><code class="c">osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument);
</code></pre>
<p>其中osThreadId被定义为k_task_t指针类型：</p>
<pre><code class="c">typedef k_task_t *osThreadId;
</code></pre>
<p>返回值：TencentOS-tiny中的任务控制块类型指针。</p>
</li>
<li><p><code>osThreadTerminate</code></p>
<pre><code class="c">osStatus osThreadTerminate(osThreadId thread_id);
</code></pre>
<p>返回值：osStatus</p>
</li>
<li><p><code>osThreadYield</code></p>
<pre><code class="c">osStatus osThreadYield(void);
</code></pre>
<p>返回值：osStatus</p>
</li>
<li><p><code>osThreadGetID</code></p>
<pre><code class="c">osThreadId osThreadGetId(void);
</code></pre>
</li>
<li><p><code>osThreadSetPriority</code></p>
<pre><code class="c">osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority);
</code></pre>
</li>
<li><p><code>osThreadGetPriority</code></p>
<pre><code class="c">osPriority osThreadGetPriority(osThreadId thread_id);
</code></pre>
</li>
</ul>
<blockquote>
<p>使用时需要特别注意，在TencentOS-tiny中，调用CMSIS-RTOS API提供的优先级选项设置之后，实际设置的任务值是不同的。</p>
</blockquote>
<p>CMSIS-RTOS API提供的线程优先级宏定义如下：</p>
<pre><code class="c">typedef enum &#123;
    osPriorityIdle          = -3,          ///&lt; priority: idle (lowest)
    osPriorityLow           = -2,          ///&lt; priority: low
    osPriorityBelowNormal   = -1,          ///&lt; priority: below normal
    osPriorityNormal        =  0,          ///&lt; priority: normal (default)
    osPriorityAboveNormal   = +1,          ///&lt; priority: above normal
    osPriorityHigh          = +2,          ///&lt; priority: high
    osPriorityRealtime      = +3,          ///&lt; priority: realtime (highest)
    osPriorityError         =  0x84        ///&lt; system cannot determine priority or thread has illegal priority
&#125; osPriority;
</code></pre>
<p>在TecentOS-tiny中实现的时候进行了转化：</p>
<pre><code class="c">static k_prio_t priority_cmsis2knl(osPriority prio)
&#123;
    if (prio == osPriorityError) &#123;
        return K_TASK_PRIO_INVALID;
    &#125;

    return (k_prio_t)(3 - prio);
&#125;

static osPriority priority_knl2cmsis(k_prio_t prio)
&#123;
    return (osPriority)(3 - prio);
&#125;
</code></pre>
<p>比如创建线程时设置为 osPriorityNormal=0，则<font color="red"><strong>实际设置的任务优先级为3</strong></font>。</p>
<h2 id="2-3-通用等待函数"><a href="#2-3-通用等待函数" class="headerlink" title="2.3. 通用等待函数"></a>2.3. 通用等待函数</h2><p>CMSIS-RTOS提供的等待函数API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osDelay</td>
<td align="center">等待指定的时间</td>
</tr>
<tr>
<td align="center">osWait（可选）</td>
<td align="center">等待信号、消息、邮箱的某个事件</td>
</tr>
</tbody></table>
<ul>
<li><code>osDelay</code><pre><code class="c">osStatus osDelay(uint32_t millisec);
</code></pre>
返回值：osStatus。</li>
</ul>
<h2 id="2-4-软件定时器管理"><a href="#2-4-软件定时器管理" class="headerlink" title="2.4. 软件定时器管理"></a>2.4. 软件定时器管理</h2><p>CMSIS-RTOS API提供的存储定时器参数的结构体如下：</p>
<pre><code class="c">typedef struct os_timer_def &#123;
    os_ptimer                 cb;   ///&lt; start address of a timer function
    k_timer_t                *timer;
&#125; osTimerDef_t;
</code></pre>
<p>CMSIS-RTOS API提供的定义一个软件定时器的宏定义如下：</p>
<pre><code class="c">#define osTimerDef(name, function)  \
    k_timer_t timer_handler_##name; \
    const osTimerDef_t os_timer_def_##name = \
        &#123; (os_ptimer)(function), (&amp;(timer_handler_##name)) &#125;
</code></pre>
<p>CMSIS-RTOS API定义的获取软件定时器参数结构体的宏如下：</p>
<pre><code class="c">#define osTimer(name) \
    &amp;os_timer_def_##name
</code></pre>
<p>CMSIS-RTOS API提供的软件定时器管理API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osTimerCreate</td>
<td align="center">创建一个软件定时器</td>
</tr>
<tr>
<td align="center">osTimerStart</td>
<td align="center">启动软件定时器</td>
</tr>
<tr>
<td align="center">osTimerStop</td>
<td align="center">停止软件定时器</td>
</tr>
<tr>
<td align="center">osTimerDelete</td>
<td align="center">删除软件定时器</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osTimerCreate</code></p>
<pre><code class="c">osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type, void *argument);
</code></pre>
<p>其中osTimerId被定义为k_timer_t指针类型：</p>
<pre><code class="c">typedef k_timer_t *osTimerId;
</code></pre>
<p>type参数为 os_timer_type 类型，表示软件定时器的类型为单次触发或者周期触发：</p>
<pre><code class="c">typedef enum  &#123;
  osTimerOnce             =     0,       ///&lt; one-shot timer
  osTimerPeriodic         =     1        ///&lt; repeating timer
&#125; os_timer_type;
</code></pre>
</li>
<li><p><code>osTimerStart</code></p>
<pre><code class="c">osStatus osTimerStart(osTimerId timer_id, uint32_t millisec);
</code></pre>
<p>返回值：osStatus。</p>
</li>
<li><p><code>osTimerStop</code></p>
<pre><code class="c">osStatus osTimerStop(osTimerId timer_id)
</code></pre>
<p>返回值：osStatus。</p>
</li>
<li><p><code>osTimerDelete</code></p>
<pre><code class="c">osStatus osTimerDelete(osTimerId timer_id);
</code></pre>
<p>返回值：osStatus。</p>
</li>
</ul>
<h2 id="2-5-信号量管理"><a href="#2-5-信号量管理" class="headerlink" title="2.5. 信号量管理"></a>2.5. 信号量管理</h2><p>CMSIS-RTOS API提供的存储信号量参数的结构体如下：</p>
<pre><code class="c">typedef struct os_semaphore_def &#123;
    uint32_t                    dummy;  ///&lt; dummy value.
    k_sem_t                    *sem;
&#125; osSemaphoreDef_t;
</code></pre>
<p>CMSIS-RTOS API提供的定义一个信号量的宏定义如下：</p>
<pre><code class="c">#define osSemaphoreDef(name)  \
    k_sem_t sem_handler_##name; \
    const osSemaphoreDef_t os_semaphore_def_##name = &#123; 0, (&amp;(sem_handler_##name)) &#125;
</code></pre>
<p>CMSIS-RTOS API定义的获取信号量参数结构体的宏如下：</p>
<pre><code class="c">#define osSemaphore(name)  \
    &amp;os_semaphore_def_##name
</code></pre>
<p>CMSIS-RTOS API提供的信号量管理API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osSemaphoreCreate</td>
<td align="center">创建一个信号量</td>
</tr>
<tr>
<td align="center">osSemaphoreWait</td>
<td align="center">等待信号量</td>
</tr>
<tr>
<td align="center">osSemaphoreRelease</td>
<td align="center">释放信号量</td>
</tr>
<tr>
<td align="center">osSemaphoreDelete</td>
<td align="center">删除信号量</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osSemaphoreCreate</code></p>
<pre><code class="c">osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, int32_t count);
</code></pre>
<p>其中 osSemaphoreId 被定义为k_sem_t指针类型：</p>
<pre><code class="c">typedef k_sem_t *osSemaphoreId;
</code></pre>
</li>
<li><p><code>osSemaphoreWait</code></p>
<pre><code class="c">int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec);
</code></pre>
<p>返回值：int32_t ，正常返回当前count数，失败返回-1。</p>
</li>
</ul>
<p>如果需要阻塞延时，参数应该设置为CMSIS-RTOS API提供的宏定义 osWaitForever ：</p>
<pre><code class="c">#define osWaitForever     0xFFFFFFFF     ///&lt; wait forever timeout value
</code></pre>
<ul>
<li><p><code>osSemaphoreRelease</code></p>
<pre><code class="c">osStatus osSemaphoreRelease(osSemaphoreId semaphore_id);
</code></pre>
<p>返回值：osStatus。</p>
</li>
<li><p><code>osSemaphoreDelete</code></p>
<pre><code class="c">osStatus osSemaphoreDelete(osSemaphoreId semaphore_id);
</code></pre>
<p>返回值：osStatus。</p>
</li>
</ul>
<h2 id="2-6-互斥锁管理"><a href="#2-6-互斥锁管理" class="headerlink" title="2.6. 互斥锁管理"></a>2.6. 互斥锁管理</h2><p>CMSIS-RTOS API提供的存储互斥锁参数的结构体如下：</p>
<pre><code class="c">typedef struct os_mutex_def &#123;
    uint32_t                    dummy;  ///&lt; dummy value.
    k_mutex_t                  *mutex;
&#125; osMutexDef_t;
</code></pre>
<p>CMSIS-RTOS API提供的定义一个互斥锁的宏定义如下：</p>
<pre><code class="c">#define osMutexDef(name)  \
    k_mutex_t mutex_handler_##name; \
    const osMutexDef_t os_mutex_def_##name = &#123; 0, (&amp;(mutex_handler_##name)) &#125;
</code></pre>
<p>CMSIS-RTOS API定义的获取互斥锁参数结构体的宏如下：</p>
<pre><code class="c">#define osMutex(name)  \
    &amp;os_mutex_def_##name
</code></pre>
<p>CMSIS-RTOS API提供的互斥锁管理API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osMutexCreate</td>
<td align="center">创建一个互斥锁</td>
</tr>
<tr>
<td align="center">osMutexWait</td>
<td align="center">等待获取互斥锁</td>
</tr>
<tr>
<td align="center">osMutexRelease</td>
<td align="center">释放互斥锁</td>
</tr>
<tr>
<td align="center">osMutexDelete</td>
<td align="center">删除互斥锁</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osMutexCreate</code></p>
<pre><code class="c">osMutexId osMutexCreate(const osMutexDef_t *mutex_def);
</code></pre>
<p>其中 osMutexId 被定义为k_mutex_t指针类型：</p>
<pre><code class="c">typedef k_mutex_t *osMutexId;
</code></pre>
</li>
<li><p><code>osMutexWait</code></p>
<pre><code class="c">osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec);
</code></pre>
<p>返回值：osStatus 。</p>
</li>
</ul>
<p>如果需要阻塞延时，参数应该设置为CMSIS-RTOS API提供的宏定义 osWaitForever ：</p>
<pre><code class="c">#define osWaitForever     0xFFFFFFFF     ///&lt; wait forever timeout value
</code></pre>
<ul>
<li><p><code>osMutexRelease</code></p>
<pre><code class="c">osStatus osMutexRelease(osMutexId mutex_id);
</code></pre>
<p>返回值：osStatus。</p>
</li>
<li><p><code>osMutexDelete</code></p>
<pre><code class="c">osStatus osMutexDelete(osMutexId mutex_id);
</code></pre>
<p>返回值：osStatus。</p>
</li>
</ul>
<h2 id="2-7-静态内存池管理"><a href="#2-7-静态内存池管理" class="headerlink" title="2.7. 静态内存池管理"></a>2.7. 静态内存池管理</h2><p>CMSIS-RTOS API提供的存储静态内存池参数的结构体如下：</p>
<pre><code class="c">typedef struct os_pool_def &#123;
    uint32_t                    pool_sz;    ///&lt; number of items (elements) in the pool
    uint32_t                    item_sz;    ///&lt; size of an item
    void                       *pool;       ///&lt; pointer to memory for pool
    k_mmblk_pool_t             *mmblk_pool; ///&lt; memory blk pool handler
&#125; osPoolDef_t;
</code></pre>
<p>CMSIS-RTOS API提供的定义一个互斥锁的宏定义如下：</p>
<pre><code class="c">#define osPoolDef(name, no, type)   \
    k_mmblk_pool_t mmblk_pool_handler_##name; \
    uint8_t mmblk_pool_buf_##name[(no) * sizeof(type)]; \
    const osPoolDef_t os_pool_def_##name = \
        &#123; (no), sizeof(type), (&amp;((mmblk_pool_buf_##name)[0])), (&amp;(mmblk_pool_handler_##name)) &#125;
</code></pre>
<p>CMSIS-RTOS API定义的获取互斥锁参数结构体的宏如下：</p>
<pre><code class="c">#define osPool(name) \
    &amp;os_pool_def_##name
</code></pre>
<p>CMSIS-RTOS API提供的互斥锁管理API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osPoolCreate</td>
<td align="center">创建一块固定大小的静态内存池</td>
</tr>
<tr>
<td align="center">osPoolAlloc</td>
<td align="center">申请分配内存</td>
</tr>
<tr>
<td align="center">osPoolCAlloc</td>
<td align="center">申请分配一块内存并全部初始化为0</td>
</tr>
<tr>
<td align="center">osPoolFree</td>
<td align="center">申请回收内存</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osPoolCreate</code></p>
<pre><code class="c">osPoolId osPoolCreate(const osPoolDef_t *pool_def);
</code></pre>
<p>其中 osPoolId 被定义为 k_mmblk_pool_t 指针类型：</p>
<pre><code class="c">typedef k_mmblk_pool_t *osPoolId;
</code></pre>
</li>
<li><p><code>osPoolAlloc</code></p>
<pre><code class="c">void *osPoolAlloc(osPoolId pool_id);
</code></pre>
</li>
<li><p><code>osPoolCAlloc</code></p>
<pre><code class="c">void *osPoolCAlloc(osPoolId pool_id);
</code></pre>
</li>
<li><p><code>osPoolFree</code></p>
<pre><code class="c">osStatus osPoolFree(osPoolId pool_id, void *block);
</code></pre>
<p>返回值：osStatus。</p>
</li>
</ul>
<h2 id="2-8-消息队列管理"><a href="#2-8-消息队列管理" class="headerlink" title="2.8. 消息队列管理"></a>2.8. 消息队列管理</h2><p>CMSIS-RTOS API提供的存储消息队列参数的结构体如下：</p>
<pre><code class="c">typedef struct os_messageQ_def &#123;
    uint32_t                    queue_sz;   ///&lt; number of elements in the queue
    uint32_t                    item_sz;    ///&lt; size of an item
    void                       *pool;       ///&lt; memory array for messages
    k_msg_q_t                  *queue;      ///&lt; queue handler
&#125; osMessageQDef_t;
</code></pre>
<p>CMSIS-RTOS API提供的定义一个消息队列的宏定义如下：</p>
<pre><code class="c">#define osMessageQDef(name, queue_sz, type)   \
    k_msg_q_t msg_q_handler_##name; \
    const osMessageQDef_t os_messageQ_def_##name = \
        &#123; (queue_sz), sizeof(type), NULL, (&amp;(msg_q_handler_##name)) &#125;
</code></pre>
<p>CMSIS-RTOS API定义的获取消息队列参数结构体的宏如下：</p>
<pre><code class="c">#define osMessageQ(name) \
    &amp;os_messageQ_def_##name
</code></pre>
<p>CMSIS-RTOS API提供的消息队列管理API如下：</p>
<table>
<thead>
<tr>
<th align="center">API</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">osMessageCreate</td>
<td align="center">初始化一个消息队列</td>
</tr>
<tr>
<td align="center">osMessagePut</td>
<td align="center">向消息队列中加入数据</td>
</tr>
<tr>
<td align="center">osMessageGet</td>
<td align="center">从消息队列中取出数据</td>
</tr>
</tbody></table>
<ul>
<li><p><code>osMessageCreate</code></p>
<pre><code class="c">osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, osThreadId thread_id);
</code></pre>
<p>其中 osMessageQId 被定义为 k_msg_q_t 指针类型：</p>
<pre><code class="c">typedef k_msg_q_t *osMessageQId;
</code></pre>
</li>
<li><p><code>osMessagePut</code></p>
<pre><code class="c">osStatus osMessagePut(osMessageQId queue_id, uint32_t info, uint32_t millisec);
</code></pre>
<p>返回值：osStatus 。</p>
</li>
</ul>
<blockquote>
<p>因为TencentOS-tiny中消息队列实现机制的不同，此API中的 millisec 参数未用到。</p>
</blockquote>
<ul>
<li><code>osMessageGet</code><pre><code class="c">osEvent osMessageGet(osMessageQId queue_id, uint32_t millisec);
</code></pre>
返回值：osEvent ，其中包含了事件信息和错误码，以及消息队列收到的值。</li>
</ul>
<p>如果需要阻塞延时，参数应该设置为CMSIS-RTOS API提供的宏定义 osWaitForever ：</p>
<pre><code class="c">#define osWaitForever     0xFFFFFFFF     ///&lt; wait forever timeout value
</code></pre>
<h1 id="3-使用示例"><a href="#3-使用示例" class="headerlink" title="3. 使用示例"></a>3. 使用示例</h1><h2 id="3-1-任务创建示例"><a href="#3-1-任务创建示例" class="headerlink" title="3.1. 任务创建示例"></a>3.1. 任务创建示例</h2><pre><code class="c">#include &lt;cmsis_os.h&gt;

void task1_entry(void *arg)
&#123;
    while(1)
    &#123;
        printf(&quot;task1 is running...\r\n&quot;);
        osDelay(1000);
    &#125;
&#125;
osThreadDef(task1_entry, osPriorityNormal, 1, 512);

void task2_entry(void *arg)
&#123;
    
    while(1)
    &#123;
        printf(&quot;task2 is running...\r\n&quot;);
        osDelay(1000);
    &#125;
&#125;
osThreadDef(task2_entry, osPriorityNormal, 1, 512);

void application_entry(void *arg)
&#123;

    osThreadCreate(osThread(task1_entry), NULL);
    osThreadCreate(osThread(task2_entry), NULL);
    
    return;
&#125;
</code></pre>
<p>任务运行结果如下：</p>
<pre><code class="c">task1 is running...
task2 is running...
task1 is running...
task2 is running...
task1 is running...
task2 is running...
</code></pre>
<h2 id="3-2-软件定时器使用示例"><a href="#3-2-软件定时器使用示例" class="headerlink" title="3.2. 软件定时器使用示例"></a>3.2. 软件定时器使用示例</h2><pre><code class="c">#include &lt;cmsis_os.h&gt;

void timer1_cb(void *arg)
&#123;
    printf(&quot;timer1 is timeout!\r\n&quot;);
&#125;

void timer2_cb(void *arg)
&#123;
    printf(&quot;timer2 is timeout!\r\n&quot;);
&#125;

osTimerDef(timer1, timer1_cb);
osTimerDef(timer2, timer2_cb);

void application_entry(void *arg)
&#123;
    osTimerId timer1;
    osTimerId timer2;
    
    timer1 = osTimerCreate(osTimer(timer1), osTimerOnce, NULL);
    timer2 = osTimerCreate(osTimer(timer2), osTimerPeriodic, NULL);
    
    osTimerStart(timer1, 5000);
    osTimerStart(timer2, 1000);
    
    return;
&#125;
</code></pre>
<p>运行结果如下：</p>
<pre><code class="c">timer2 is timeout!
timer2 is timeout!
timer2 is timeout!
timer2 is timeout!
timer1 is timeout!
timer2 is timeout!
timer2 is timeout!
timer2 is timeout!
timer2 is timeout!
</code></pre>
<h2 id="3-3-信号量使用示例"><a href="#3-3-信号量使用示例" class="headerlink" title="3.3. 信号量使用示例"></a>3.3. 信号量使用示例</h2><pre><code class="c">#include &lt;cmsis_os.h&gt;

osSemaphoreId sync_sem_id;
osSemaphoreDef(sync_sem);

void task1_entry(void *arg)
&#123;
    while(1)
    &#123;
        printf(&quot;task1 is waiting sem forever...\r\n&quot;);
        osSemaphoreWait(sync_sem_id, osWaitForever);
        printf(&quot;task1 get sem!\r\n&quot;);
    &#125;
&#125;
osThreadDef(task1_entry, osPriorityNormal, 1, 512);

void task2_entry(void *arg)
&#123;
    
    while(1)
    &#123;
        printf(&quot;task2 will release a sem...\r\n&quot;);
        osSemaphoreRelease(sync_sem_id);
        osDelay(1000);
    &#125;
&#125;
osThreadDef(task2_entry, osPriorityNormal, 1, 512);

void application_entry(void *arg)
&#123;
    sync_sem_id = osSemaphoreCreate(osSemaphore(sync_sem), 0);

    osThreadCreate(osThread(task1_entry), NULL);
    osThreadCreate(osThread(task2_entry), NULL);
    
    return;
&#125;
</code></pre>
<p>运行结果为：</p>
<pre><code class="c">task1 is waiting sem forever...
task1 get sem!
task1 is waiting sem forever...
task2 will release a sem...
task1 get sem!
task1 is waiting sem forever...
task2 will release a sem...
task1 get sem!
task1 is waiting sem forever...
task2 will release a sem...
task1 get sem!
task1 is waiting sem forever...
task2 will release a sem...
task1 get sem!
task1 is waiting sem forever...
</code></pre>
<h2 id="3-4-互斥锁使用示例"><a href="#3-4-互斥锁使用示例" class="headerlink" title="3.4. 互斥锁使用示例"></a>3.4. 互斥锁使用示例</h2><pre><code class="c">#include &lt;cmsis_os.h&gt;

osMutexId sync_mutex_id;
osMutexDef(sync_mutex);

void task1_entry(void *arg)
&#123;
    while(1)
    &#123;
        osMutexWait(sync_mutex_id, osWaitForever);
        
        printf(&quot;task1 get mutex,doing sth...\r\n&quot;);
        HAL_Delay(1000);    //死循环占用CPU
        printf(&quot;task1 finish do sth!\r\n&quot;);
        
        osMutexRelease(sync_mutex_id);
        
        osDelay(1000);
    &#125;
&#125;
osThreadDef(task1_entry, osPriorityHigh, 1, 512);

void task2_entry(void *arg)
&#123;
    
    while(1)
    &#123;
        osMutexWait(sync_mutex_id, osWaitForever);
        
        printf(&quot;task2 get mutex,doing sth...\r\n&quot;);
        HAL_Delay(2000);    //死循环占用CPU
        printf(&quot;task2 finish do sth!\r\n&quot;);
        
        osMutexRelease(sync_mutex_id);
        
        osDelay(1000);
    &#125;
&#125;
osThreadDef(task2_entry, osPriorityNormal, 1, 512);

void application_entry(void *arg)
&#123;
    sync_mutex_id = osMutexCreate(osMutex(sync_mutex));

    osThreadCreate(osThread(task1_entry), NULL);
    osThreadCreate(osThread(task2_entry), NULL);
    
    return;
&#125;
</code></pre>
<p>运行结果为：</p>
<pre><code class="c">task1 get mutex,doing sth...
task1 finish do sth!
task2 get mutex,doing sth...
task2 finish do sth!
task1 get mutex,doing sth...
task1 finish do sth!
task1 get mutex,doing sth...
task1 finish do sth!
task2 get mutex,doing sth...
</code></pre>
<h2 id="3-5-动态内存使用示例"><a href="#3-5-动态内存使用示例" class="headerlink" title="3.5. 动态内存使用示例"></a>3.5. 动态内存使用示例</h2><pre><code class="c">#include &lt;cmsis_os.h&gt;

typedef struct blk_st &#123;
    int   id;
    char* payload;
&#125; blk_t;

#define MMBLK_BLK_NUM 10

osPoolDef (MemPool, MMBLK_BLK_NUM, blk_t);
osPoolId mem_pool_id;

void task1_entry(void *arg)
&#123;   
    
    blk_t *ptr = NULL;
    osStatus err;
    
    /* 打印出一个块的大小 */
    printf(&quot;block size is %d bytes\r\n&quot;, sizeof(blk_t));
    
    /* 申请一个块 */
    ptr = osPoolAlloc(mem_pool_id);
    if (ptr == NULL) &#123;
        printf(&quot;a mmblk alloc fail\r\n&quot;);
        return;
    &#125;
    else &#123;
        printf(&quot;a mmblk alloc success\r\n&quot;);
    &#125;
    
    /* 使用该块 */
    ptr-&gt;id = 1;
    ptr-&gt;payload = &quot;hello&quot;;
    printf(&quot;mmblk id:%d payload:%s\r\n&quot;, ptr-&gt;id, ptr-&gt;payload);
    
    /* 使用完毕之后释放 */
    err = osPoolFree(mem_pool_id, ptr);
    if (err != osOK) &#123;
        printf(&quot;a mmblk free fail, err = %d\r\n&quot;, err);
        return;
    &#125;
    else &#123;
        printf(&quot;a mmblk free success\r\n&quot;);
    &#125;
    
    while (1) &#123;
        tos_task_delay(1000);
    &#125;
&#125;

#define STK_SIZE_TASK1      1024
osThreadDef(task1_entry, osPriorityNormal, 1, STK_SIZE_TASK1);

void application_entry(void *arg)
&#123;
    //初始化静态内存池
    mem_pool_id = osPoolCreate(osPool(MemPool));
    if (mem_pool_id == NULL) &#123;
        printf(&quot;mmblk pool create fail\r\n&quot;);
        return;
    &#125;
    else &#123;
        printf(&quot;mmblk pool create success\r\n&quot;);
    &#125;

    //创建任务
    osThreadCreate(osThread(task1_entry), NULL);

    return;
&#125;
</code></pre>
<p>运行结果为：</p>
<pre><code>mmblk pool create success
block size is 8 bytes
a mmblk alloc success
mmblk id:1 payload:hello
a mmblk free success
</code></pre>
<h2 id="3-6-消息队列使用示例"><a href="#3-6-消息队列使用示例" class="headerlink" title="3.6. 消息队列使用示例"></a>3.6. 消息队列使用示例</h2><pre><code class="c">#include &lt;cmsis_os.h&gt;

#define STK_SIZE_TASK_RECEIVER      512
#define STK_SIZE_TASK_SENDER        512

#define MESSAGE_MAX     10

osMessageQId msg_q_id;
osMessageQDef(msg_q,MESSAGE_MAX,uint32_t);

void task_receiver_entry(void *arg)
&#123;
    osEvent event;
    osStatus ret;
    uint32_t value;

    while (1)
    &#123;
        event = osMessageGet(msg_q_id, osWaitForever);
        ret = event.status;
        if (ret == osOK)
        &#123;
            value = event.value.v;
            printf(&quot;receiver: msg incoming[%s]\r\n&quot;, (char*)value);
        &#125;
    &#125;
&#125;
osThreadDef(task_receiver_entry, osPriorityNormal, 1, STK_SIZE_TASK_RECEIVER);

void task_sender_entry(void *arg)
&#123;
    char *msg_prio_0 = &quot;msg 0&quot;;
    char *msg_prio_1 = &quot;msg 1&quot;;
    char *msg_prio_2 = &quot;msg 2&quot;;

    printf(&quot;sender: post a messgae:[%s]\r\n&quot;, msg_prio_2);
    osMessagePut(msg_q_id,(uint32_t)msg_prio_2,0);
    
    printf(&quot;sender: post a messgae:[%s]\r\n&quot;, msg_prio_1);
    osMessagePut(msg_q_id,(uint32_t)msg_prio_1,0);
    
    printf(&quot;sender: post a messgae:[%s]\r\n&quot;, msg_prio_0);
    osMessagePut(msg_q_id,(uint32_t)msg_prio_0,0);

&#125;
osThreadDef(task_sender_entry, osPriorityNormal, 1, STK_SIZE_TASK_SENDER);

void application_entry(void *arg)
&#123;
    msg_q_id = osMessageCreate(osMessageQ(msg_q),NULL);

    osThreadCreate(osThread(task_receiver_entry), NULL);
    osThreadCreate(osThread(task_sender_entry), NULL);
    
    return;
&#125;
</code></pre>
<p>运行结果为：</p>
<pre><code class="c">sender: post a messgae:[msg 2]
sender: post a messgae:[msg 1]
sender: post a messgae:[msg 0]
receiver: msg incoming[msg 2]
receiver: msg incoming[msg 1]
receiver: msg incoming[msg 0]
</code></pre>
<p><font color="red"><strong>接收更多精彩文章及资源推送，欢迎订阅我的微信公众号：『mculover666』。</strong></font><br><img src="https://img-blog.csdnimg.cn/20200202092055136.png"></p>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">Mculover666</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="http://www.mculover666.cn/posts/2358419088/">http://www.mculover666.cn/posts/2358419088/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">Mculover666</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/RTOS%E5%86%85%E5%8A%9F%E4%BF%AE%E7%82%BC%E8%AE%B0/">
                                    <span class="chip bg-color">RTOS内功修炼记</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.png" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/we-chat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    
    <div class="livere-card card" data-aos="fade-up">
    <!-- 来必力City版安装代码 -->
    <div id="lv-container" class="card-content" data-id="city" data-uid="MTAyMC80Njg0OS8yMzM1MA">
        <script type="text/javascript">
            (function (d, s) {
                let j, e = d.getElementsByTagName(s)[0];
                if (typeof LivereTower === 'function') {
                    return;
                }

                j = d.createElement(s);
                j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
                j.async = true;

                e.parentNode.insertBefore(j, e);
            })(document, 'script');
        </script>
        <noscript>为正常使用来必力评论功能请激活JavaScript。</noscript>
    </div>
    <!-- City版安装代码已完成 -->
</div>
    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/posts/30779210/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/12.jpg" class="responsive-img" alt="ringbuff | 通用FIFO环形缓冲区实现库">
                        
                        <span class="card-title">ringbuff | 通用FIFO环形缓冲区实现库</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            嵌入式开源项目精选专栏
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2020-08-02
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/OpenSource/" class="post-category">
                                    OpenSource
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%E7%B2%BE%E9%80%89%E4%B8%93%E6%A0%8F/">
                        <span class="chip bg-color">嵌入式开源项目精选专栏</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/posts/1391422127/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/10.jpg" class="responsive-img" alt="07-动态内存和静态内存管理机制">
                        
                        <span class="card-title">07-动态内存和静态内存管理机制</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            RTOS内功修炼记
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2020-08-01
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/RTOS/" class="post-category">
                                    RTOS
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/RTOS%E5%86%85%E5%8A%9F%E4%BF%AE%E7%82%BC%E8%AE%B0/">
                        <span class="chip bg-color">RTOS内功修炼记</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h1, h2, h3, h4, h5, h6'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h1, h2, h3, h4, h5, h6').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
    <div class="container row center-align" style="margin-bottom: 15px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2016-2021</span>
            
            <span id="year">2016</span>
            <a href="/about" target="_blank">Mculover666</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">118.4k</span>&nbsp;字
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <span id="sitetime">载入运行时间...</span>
            <script>
                function siteTime() {
                    var seconds = 1000;
                    var minutes = seconds * 60;
                    var hours = minutes * 60;
                    var days = hours * 24;
                    var years = days * 365;
                    var today = new Date();
                    var startYear = "2016";
                    var startMonth = "8";
                    var startDate = "28";
                    var startHour = "0";
                    var startMinute = "0";
                    var startSecond = "0";
                    var todayYear = today.getFullYear();
                    var todayMonth = today.getMonth() + 1;
                    var todayDate = today.getDate();
                    var todayHour = today.getHours();
                    var todayMinute = today.getMinutes();
                    var todaySecond = today.getSeconds();
                    var t1 = Date.UTC(startYear, startMonth, startDate, startHour, startMinute, startSecond);
                    var t2 = Date.UTC(todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond);
                    var diff = t2 - t1;
                    var diffYears = Math.floor(diff / years);
                    var diffDays = Math.floor((diff / days) - diffYears * 365);
                    var diffHours = Math.floor((diff - (diffYears * 365 + diffDays) * days) / hours);
                    var diffMinutes = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours) /
                        minutes);
                    var diffSeconds = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours -
                        diffMinutes * minutes) / seconds);
                    if (startYear == todayYear) {
                        document.getElementById("year").innerHTML = todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffDays + " 天 " + diffHours +
                            " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    } else {
                        document.getElementById("year").innerHTML = startYear + " - " + todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffYears + " 年 " + diffDays +
                            " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    }
                }
                setInterval(siteTime, 1000);
            </script>
            
            <br>
            
            <span id="icp"><img src="/medias/icp.png" style="vertical-align: text-bottom;" />
                <a href="https://beian.miit.gov.cn" target="_blank">陇ICP备19002222号</a>
            </span>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/Mculover666" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:mculover666@foxmail.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2412828003" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 2412828003" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>





    <a href="https://www.zhihu.com/people/wang-shi-wei-67-38/activities" class="tooltipped" target="_blank" data-tooltip="关注我的知乎: https://www.zhihu.com/people/wang-shi-wei-67-38/activities" data-position="top" data-delay="50">
        <i class="fab fa-zhihu1">知</i>
    </a>



    <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
        <i class="fas fa-rss"></i>
    </a>

</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

<script>
    var _hmt = _hmt || [];
    (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?6e1efa0988723a1db6356535db2ae6bd";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

    <!--腾讯兔小巢-->
    
    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
